package com.z1.core.data.export.ftl;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
import java.util.Map;

import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import com.itextpdf.text.pdf.BaseFont;
import com.z1.core.exception.Z1Exception;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class FreemarkerUtil {

	private Configuration cfg = null;
	
	public FreemarkerUtil() {
		loadTemplateFormClassPath();
	}
	public FreemarkerUtil(File dir) {
		if (null != dir) {
			loadTemplateFormDirectory(dir);
		}
		else { loadTemplateFormClassPath(); }
		if (null != this.cfg) {
			this.cfg.setDefaultEncoding("UTF-8");
		}
	}
	
	/**
	 * 加载模板的方式：从ClassPath中获取
	 */
	private void loadTemplateFormClassPath() {
		String pathPrefix = this.getClass().getPackage().getName();
		pathPrefix = "/" + pathPrefix.replaceAll("\\.", "/");
		loadTemplateFormClassPath(this.getClass(), "/ftl");
	}
	private void loadTemplateFormClassPath(Class<?> clazz, String pathPrefix) {
		this.cfg = new Configuration();
		this.cfg.setClassForTemplateLoading(clazz, pathPrefix);
	}
	
	/**
	 * 加载模板的方式：从指定的目录中获取
	 * @param dir 模板目录
	 */
	private void loadTemplateFormDirectory(File dir) {
		this.cfg = new Configuration();
		try {
			this.cfg.setDirectoryForTemplateLoading(dir);
		}
		catch (Throwable e) {
			throw new Z1Exception(e);
		}
	}
	
	private Template getTemplate(String name) {
		try {
            return cfg.getTemplate(name);
        }
		catch (Throwable e) {
            throw new Z1Exception(e); 
        }
	}
	
	public void printToHtml(String name, Map<String, Object> root, OutputStream out) {
		if (null == name) { throw new Z1Exception("模板名不存在."); }
		if (null == out) { out = System.out; }
        try {
            Template template = getTemplate(name);
            if (null == template) { throw new Exception("模板(" + name + ")不存在."); }
            
            template.setEncoding("UTF-8");
            
            template.process(root, new PrintWriter(out));
            out.flush();
        }
        catch (Throwable e) {
        	throw new Z1Exception(e);
        }
    }
	
	public void printToHtml(String name, Map<String, Object> root, File file) {
		if (null == file) { throw new Z1Exception("文件参数为null."); }
		OutputStream output = null;
		try {
			output = new FileOutputStream(file);
			printToHtml(name, root, output);
		}
		catch (Throwable e) {
			throw new Z1Exception(e);
		}
		finally {
            try {
                if (output != null) { output.close(); }
            }
            catch (Throwable e) { }
        }
	}
	
	public void printToPdf(String name, Map<String, Object> root, OutputStream out) {
		try {
			URI uri = FreemarkerUtil.class.getResource("/simsun.ttc").toURI();
			printToPdf(name, root, out, new File(uri));
		}
		catch (Throwable e) {
			e.printStackTrace();
//			throw new Z1Exception(e);
		}
	}
	public void printToPdf(String name, Map<String, Object> root, OutputStream out, File fontFile) {
		if (null == name) { throw new Z1Exception("模板名不存在."); }
		if (null == out) {
			printToPdf(name, root, System.out);
			return;
		}
        try {
            Template template = getTemplate(name);
            if (null == template) { throw new Exception("模板(" + name + ")不存在."); }
            
            template.setEncoding("UTF-8");   
            
            StringWriter stringWriter = null;   
            BufferedWriter writer = null;
            String htmlStr = "";
            try {
            	stringWriter = new StringWriter();
            	writer = new BufferedWriter(stringWriter);
            	template.process(root, writer);       
            	htmlStr = stringWriter.toString();
            	writer.flush();
            }
            catch (Throwable e) {
            	throw e;
            }
            finally {
            	if (null != writer) { writer.close(); }
            	if (null != stringWriter) { stringWriter.close(); }
            }
            
			ITextRenderer renderer = new ITextRenderer();
			renderer.setScaleToFit(true);
			renderer.setDocumentFromString(htmlStr);
//			DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
//          Document doc = builder.parse(new ByteArrayInputStream(htmlStr.getBytes()));
//			renderer.setDocument(doc, null);
            
			// 解决中文支持问题
			ITextFontResolver fontResolver = renderer.getFontResolver();
			fontResolver.addFont(fontFile.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
 
			renderer.layout();
			renderer.createPDF(out);
//			renderer.createPDF(out, true);
			out.flush();
			System.err.println("生成pdf成功");
        }
        catch (Throwable e) {
        	e.printStackTrace();
//        	throw new Z1Exception(e);
        }
	}
	
	public void printToPdf(String name, Map<String, Object> root, File file) {
		if (null == file) { throw new Z1Exception("文件参数为null."); }
		OutputStream output = null;
		try {
			output = new FileOutputStream(file);
			printToPdf(name, root, output);
		}
		catch (Throwable e) {
			e.printStackTrace();
			throw new Z1Exception(e);
		}
		finally {
            try {
                if (output != null) { output.close(); }
            }
            catch (Throwable e) { }
        }
	}
	
}
